package com.spstudio.iforward.end.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.inject.Inject;

import com.spstudio.iforward.core.qualifier.SPCoreLogged;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class PictureDownloadUtil {

	@Inject @SPCoreLogged Logger log;
	
	private static final String supportedType = "JPG,JPEG,PNG";
	public static final String RECOMMAND_THUMBNAIL = "RECOMMAND_THUMBNAIL";
	private static int MAX_WIDTH = 640;
	
	private String saveDir;
	private String[] pictureUrls;
	private TaskTimer timer;
	private ConcurrentMap<String, String> map;

	public PictureDownloadUtil(String saveDir, String[] pictureUrls) {
		this.saveDir = saveDir;
		this.pictureUrls = pictureUrls;
		timer = new TaskTimer(pictureUrls.length);
	}

	public ConcurrentMap<String, String> download() throws InterruptedException{
		if (pictureUrls == null || pictureUrls.length == 0) {
			return null;
		}
		
		map = new ConcurrentHashMap<String, String>();
		for (final String pictureUrl : pictureUrls) {
			new Thread() {
				public void run() {
					
					int lastIndex = pictureUrl.lastIndexOf(".");
					String ext = null;
					if (lastIndex != -1){
						ext = pictureUrl.substring(lastIndex + 1);
						if (ext != null){
							
							if (ext.length() == 0){
								log.log(Level.WARNING, "blank file suffix detected - " + pictureUrl);
								return;
							}
							if (supportedType.indexOf(ext.toUpperCase()) == -1){
								log.log(Level.WARNING, "not supporting file suffix detected - " + pictureUrl);
								return;
							}
							
							try{
								// save original picture
								URL url = new URL(pictureUrl);
								InputStream is = url.openStream();
								String newFileName = UUID.randomUUID().toString().replace("-", "") + "." + ext;
								String newFilePath = saveDir + File.separator + newFileName;
								OutputStream os = new FileOutputStream(newFilePath + ".tmp");
								int bytesRead = 0;
								byte[] buffer = new byte[8192];
								while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
									os.write(buffer, 0, bytesRead);
								}
								os.flush();
								os.close();
								is.close();
								
								// resize picture
								resize2(newFilePath + ".tmp", newFilePath, pictureUrl);
								
								// delete original picture
								new File(newFilePath + ".tmp").delete();
								
								map.put(pictureUrl, newFileName);
							}catch(Exception e){
								e.printStackTrace();
								log.log(Level.SEVERE, e.getMessage());
							}
						}else{
							log.log(Level.WARNING, "can't find file suffix from url - " + pictureUrl);
						}
					}
					timer.completeTask();
				}
			}.start();
		}
		synchronized (timer) {
			timer.wait(30000);
		}
		
		// set default value
		if (!map.containsKey(RECOMMAND_THUMBNAIL)){
			map.put(RECOMMAND_THUMBNAIL, pictureUrls[0]);
		}
		return map;
	}
	
	private void resize2(String originalImagePath, String resizedImagePath, String originalUrl) throws IOException{
		BufferedImage originalImage = ImageIO.read(new File(originalImagePath));

        int newWidth = originalImage.getWidth();
		int newHeight = originalImage.getHeight();
		
		if (newWidth > newHeight){
			if (map.containsKey(RECOMMAND_THUMBNAIL)){
				int currentPictureIndex = 0;
				int pictureInMapIndex = 0;
				String pictureInMap = map.get(RECOMMAND_THUMBNAIL);
				for(int i = 0; i < pictureUrls.length; i ++){
					if (originalUrl.equals(pictureUrls[i])){
						currentPictureIndex = i;
						continue;
					}
					if (pictureInMap.equals(pictureUrls[i])){
						pictureInMapIndex = i;
						continue;
					}
				}
				if (currentPictureIndex <= pictureInMapIndex){
					map.put(RECOMMAND_THUMBNAIL, originalUrl);
				}
			}else{
				map.put(RECOMMAND_THUMBNAIL, originalUrl);
			}
		}
		
        // 判断如果高、宽都不大于设定值，则不处理
        if (originalImage.getWidth() > MAX_WIDTH) {
        	float radio = MAX_WIDTH * 1f / newWidth;
			newWidth = MAX_WIDTH;
			newHeight = (int)(newHeight * radio);
        }

        BufferedImage bfImage = new BufferedImage(newWidth, newHeight,
                BufferedImage.TYPE_INT_RGB);
        bfImage.getGraphics().drawImage(
                originalImage.getScaledInstance(newWidth, newHeight,
                        Image.SCALE_SMOOTH), 0, 0, null);

        FileOutputStream os = new FileOutputStream(new File(resizedImagePath));
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
        encoder.encode(bfImage);
        os.close();
	}

	class TaskTimer {
		private int taskCount;

		public TaskTimer(int taskCount){
			this.taskCount = taskCount;
		}
		public int getTaskCount() {
			return taskCount;
		}

		public void setTaskCount(int taskCount) {
			this.taskCount = taskCount;
		}
		
		synchronized public void completeTask(){
			taskCount --;
			if (taskCount == 0){
				notify();
			}
		}
	}
	
	public static void main(String args[]){
		System.out.println(UUID.randomUUID().toString().replace("-", ""));
	}
}
